using MicroMsg.Common.Utils;
using MicroMsg.Protocol;
using System;
namespace MicroMsg.Network
{
	public class Sender
	{
		private static int mRetryAuthLeft = 3;
		private static bool mDisableSender = false;
		public static Sender gSender = null;
		public static Sender getInstance()
		{
			if (Sender.gSender == null)
			{
				Sender.gSender = new Sender();
			}
			return Sender.gSender;
		}
		public bool sendPack(SessionPack sessionPack)
		{
			if (sessionPack == null)
			{
				Log.smethod_1("Network", "CMD to Network: null pack");
				return false;
			}
			Log.smethod_4("Network", string.Concat(new object[]
			{
				"CMD to Network: cmd=",
				(CmdConst)sessionPack.mCmdID,
				" seq=",
				sessionPack.mSeqID
			}));
			Sender.mRetryAuthLeft = 3;
			Connector.onPrepareSend(false);
			LongConnector.setEnable(true);
			if (sessionPack.mCmdID == 1 && SessionPackMgr.isAuthing())
			{
				Log.smethod_1("Network", "isAuthing, don't send auth request");
				return false;
			}
			if (sessionPack.mCmdID == 1)
			{
				SessionPackMgr.putToHead(sessionPack);
			}
			else
			{
				SessionPackMgr.putToTail(sessionPack);
			}
			NetHandler.wakeUp();
			return true;
		}
		public void logoutAccount()
		{
			Log.smethod_4("Network", "CMD to network , logout account.");
			Sender.mDisableSender = true;
		}
		public void checkSender()
		{
			if (Sender.mDisableSender)
			{
				Sender.mDisableSender = false;
				this.closeSender();
			}
		}
		public void closeSender()
		{
			Log.smethod_4("Network", "close sender , clearn all.");
			LongConnector.setEnable(false);
			Connector.close();
			SessionPackMgr.cancelAllPacket();
			SessionPackMgr.getAccount().reset();
			SessionPackMgr.setAuthStatus(0);
		}
		public bool sendAutoAuthPack()
		{
			SessionPack sessionPack = AuthPack.makeAutoAuthPack(2);
			return this.sendPack(sessionPack);
		}
		public bool handler()
		{
			if (!NetworkDeviceWatcher.isNetworkAvailable())
			{
				return false;
			}
			SessionPack firstNotSended = SessionPackMgr.getFirstNotSended();
			if (firstNotSended == null)
			{
				return false;
			}
			if (SessionPackMgr.isAuthing())
			{
				return false;
			}
			if (!Connector.isValidforPack(firstNotSended))
			{
				return false;
			}
			if (!this.checkSessionKey(ref firstNotSended))
			{
				return false;
			}
			if (!this.preProcessPack(firstNotSended))
			{
				Log.smethod_1("Network", "Sender: Failed to PreProcess pack.");
				return false;
			}
			return this.doSendPack(firstNotSended);
		}
		private bool needSessionKey(SessionPack sessionPack)
		{
			return sessionPack.mCmdID != 33 && sessionPack.mCmdID != 48 && (sessionPack.mCmdID != 0 || (!sessionPack.mCmdUri.Equals("/cgi-bin/micromsg-bin/bindopmobileforreg") && !sessionPack.mCmdUri.Equals("/cgi-bin/micromsg-bin/getresetpwdurl")));
		}
		private bool checkSessionKey(ref SessionPack sessionPack)
		{
			if (sessionPack.mCmdID == 1)
			{
				AuthPack.updateAccountInfoFromAuth(sessionPack.mRequestObject);
				return true;
			}
			if (sessionPack.mCmdID == 32)
			{
				AuthPack.updateAccountInfoFromNewReg(sessionPack.mRequestObject);
				return true;
			}
			if (sessionPack.mCmdID == 31)
			{
				AuthPack.updateAccountInfoFromReg(sessionPack.mRequestObject);
				return true;
			}
			if (!this.needSessionKey(sessionPack))
			{
				return true;
			}
			if (SessionPackMgr.isValidSessionKey())
			{
				return true;
			}
			this.checkTryAutoAuth();
			return false;
		}
		public bool checkTryAutoAuth()
		{
			if (!SessionPackMgr.getAccount().isValid())
			{
				Log.smethod_1("Network", "cannot auto-auth without valid account.");
				this.closeSender();
				return false;
			}
			if (Sender.mRetryAuthLeft <= 0)
			{
				if (Sender.mRetryAuthLeft == 0)
				{
					Log.smethod_1("Network", " autoAuth no retry left");
					Sender.mRetryAuthLeft = -1;
				}
				return false;
			}
			SessionPackMgr.getPackEx(delegate(SessionPack pack)
			{
				if (pack.mCacheBodyBuffer != null)
				{
					Log.smethod_4("Network", "clearn cache body before autoauth, cmdUri = " + pack.mCmdUri);
					pack.mCacheBodyBuffer = null;
				}
				return true;
			});
			Log.smethod_4("Network", "CMD need autoauth, autoAuthLeft:" + Sender.mRetryAuthLeft);
			Sender.mRetryAuthLeft--;
			SessionPack sessionPack = AuthPack.makeAutoAuthPack(2);
			SessionPackMgr.putToHead(sessionPack);
			return true;
		}
		private bool preProcessPack(SessionPack sessionPack)
		{
			if (sessionPack.mRetryLeft <= 0)
			{
				Log.smethod_1("Network", "sender: retryLeft =0,cmd =:" + (CmdConst)sessionPack.mCmdID);
				sessionPack.mSendStatus = 6;
				OnCallback.onError(sessionPack, PackResult.RETRY_LIMIT);
				return false;
			}
			if (sessionPack.mCanceled)
			{
				Log.smethod_1("Network", "not send packet been cancelled.)");
				return false;
			}
			if (sessionPack.mCmdID != 6 && sessionPack.mRetryLeft != 3)
			{
				int seqID = SessionPack.getSeqID();
				Log.smethod_5("Network", string.Concat(new object[]
				{
					"resend pack, change seq ",
					sessionPack.mSeqID,
					" to new seq ",
					seqID
				}));
				SessionPackMgr.changeSessionPackSeq(sessionPack.mSeqID, seqID);
				sessionPack.mSeqID = seqID;
			}
			sessionPack.mRetryLeft--;
			sessionPack.mSendStatus = 1;
			if (sessionPack.mCacheBodyBuffer != null)
			{
				return true;
			}
			if (sessionPack.mCmdID != 8)
			{
				if (sessionPack.mCmdID != 25)
				{
					if (!MMPack.EncodePack(sessionPack))
					{
						Log.smethod_1("Network", "sender.encodePack failed,cmd= " + (CmdConst)sessionPack.mCmdID);
						sessionPack.mCacheBodyBuffer = null;
						sessionPack.mSendStatus = 6;
						OnCallback.onError(sessionPack, PackResult.PACK_ERROR);
						return false;
					}
					return true;
				}
			}
			sessionPack.mCacheBodyBuffer = sessionPack.requestToByteArray();
			if (sessionPack.mCacheBodyBuffer == null)
			{
				Log.smethod_1("Network", "newsync check got bytearray failed.");
				sessionPack.mSendStatus = 6;
				OnCallback.onError(sessionPack, PackResult.PACK_ERROR);
				return false;
			}
			return true;
		}
		private bool doSendPack(SessionPack sessionPack)
		{
			sessionPack.mSendStatus = 2;
			if (sessionPack.mCmdID == 1)
			{
				Log.smethod_4("Network", "auth now...user = " + SessionPackMgr.getAccount().getUsername());
				SessionPackMgr.setAuthStatus(1);
			}
			if (sessionPack.mCmdID == 8)
			{
				sessionPack.mSendStatus = 4;
			}
			else
			{
				sessionPack.setTimeoutPoint();
			}
			if (!Connector.sendPack(sessionPack))
			{
				this.onSendPackFailed(true, sessionPack);
				return false;
			}
			if (sessionPack.mCmdID != 6)
			{
				if (sessionPack.mCmdID != 8)
				{
					sessionPack.mSendStatus = 3;
					return true;
				}
			}
			sessionPack.mSendStatus = 5;
			return true;
		}
		public void onSendPackFailed(bool needReconnect, SessionPack sessionPack)
		{
			Log.smethod_1("Network", string.Concat(new object[]
			{
				"sender:onSendPackFailed, seq =",
				sessionPack.mSeqID,
				", cmd =",
				sessionPack.mCmdID
			}));
			SessionPackMgr.cleanAllTimeoutPoint(sessionPack.mConnectMode);
			SessionPackMgr.markAllToNotSended(sessionPack.mConnectMode);
			if (SessionPackMgr.getAuthStatus() == 1)
			{
				SessionPackMgr.setAuthStatus(0);
			}
			Connector.onSendFailed(needReconnect, sessionPack.mConnectMode);
		}
		public void onSendTimeout(SessionPack sessionPack)
		{
			Log.smethod_1("Network", string.Concat(new object[]
			{
				"sender:onSendTimeout, seq =",
				sessionPack.mSeqID,
				", cmd =",
				sessionPack.mCmdID
			}));
			this.onSendPackFailed(true, sessionPack);
		}
	}
}
